package org.xteam.box2text.parser;

import java_cup.runtime.*;
import org.xteam.box2text.parser.IBoxTokens;

import org.xteam.parser.runtime.IErrorReporter;

%%

%class BoxLexer
%implements IBoxTokens
%cupsym IBoxTokens
%cup
%public
%char

DIGIT		= [0-9]
LETTER		= [a-zA-Z_]
IDENT		= {LETTER}({LETTER}|{DIGIT})*

%{

	private StringBuffer buffer = new StringBuffer();
	private IErrorReporter reporter;
	private int start;
	
	public BoxLexer(java.io.Reader reader, IErrorReporter reporter) {
		this(reader);
		this.reporter = reporter;
	}

	public Symbol symbol(int kind) {
		return new Symbol(kind, yychar, yychar+yylength(), null);
	}
	
	public Symbol symbol(int kind, Object value) {
		return new Symbol(kind, yychar, yychar+yylength(), value);
	}
	
	public Symbol symbol(int kind, int start, int end, Object value) {
		return new Symbol(kind, start, end, value);
	}
	
%}

%state STR

%%

<YYINITIAL> {

"{"[^}]*"}" 			{ /* ignore comments */ }
[ \t\f\r\b\n]+		{ /* ignore white spaces */ }

"import"		{ return symbol(IBoxTokens.IMPORT); }

"[["			{ return symbol(IBoxTokens.RECL); }
"]]"			{ return symbol(IBoxTokens.RECR); }
"["			{ return symbol(IBoxTokens.LBRT); }
"]"			{ return symbol(IBoxTokens.RBRT); }
"("			{ return symbol(IBoxTokens.LPAR); }
")"			{ return symbol(IBoxTokens.RPAR); }
"<%"			{ return symbol(IBoxTokens.CMDL); }
"%>"			{ return symbol(IBoxTokens.CMDR); }
"<"			{ return symbol(IBoxTokens.LT); }
">"			{ return symbol(IBoxTokens.GT); }
","			{ return symbol(IBoxTokens.COMA); }
"="			{ return symbol(IBoxTokens.EQUALS); }
"\."			{ return symbol(IBoxTokens.DOT); }
"\'"		{ start = yychar; buffer.setLength(0); yybegin(STR); }

{IDENT}		{ return symbol(IBoxTokens.ID, yytext()); }
{DIGIT}+		{ return symbol(IBoxTokens.INTEGER, yytext()); }
.			{ reporter.reportError(yychar, 1, "bad character \'"+yycharat(0)+"\'");
				throw new java.io.IOException("bad character \'"+yycharat(0)+"\'"); }
<<EOF>>		{ return symbol(IBoxTokens.EOF); }
}

<STR> {
"\'"				{ yybegin(YYINITIAL); return symbol(IBoxTokens.STRING, start, yychar + yylength(), buffer.toString()); }
[^\'\n]+			{ buffer.append(yytext()); }
"\'\'"				{ buffer.append('\''); }
[\n]				{ reporter.reportError(start, yychar-start, "unterminated string");
						yybegin(YYINITIAL); return symbol(IBoxTokens.STRING, buffer.toString()); }
}
